package com.ruoyi.web.controller.video;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.text.UnicodeUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.*;
import com.ruoyi.common.utils.android.DecryptString;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.security.AesUtil;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDictTypeService;
import com.ruoyi.video.domain.*;
import com.ruoyi.video.domain.dto.PromDetailDTO;
import com.ruoyi.video.domain.dto.PromListDetailDTO;
import com.ruoyi.video.domain.vo.*;
import com.ruoyi.video.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 视频 信息操作处理
 * 
 * @author ruoyi
 */
@Api("外部接口管理")
@RestController
@RequestMapping("/bus/outer")
public class BusOuterController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(BusOuterController.class);

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private ISysConfigService configService;

    @Autowired
    private IVideoInfoService videoInfoService;

    @Autowired
    private ISysDictTypeService dictTypeService;

    @Autowired
    private IActiveCodeService activeCodeService;

    @Autowired
    private IMemberInfoService memberInfoService;

    @Autowired
    private IMemberStoreService memberStoreService;

    @Autowired
    private ICarouselInfoService carouselInfoService;

    @Autowired
    private IDownloadInfoService downloadInfoService;

    private String liveLogin() {
        String liveLoginParam = configService.selectConfigByKey("live_param");
        String liveLoginUrl = configService.selectConfigByKey("live_login");
        log.info("第三方登录接口参数: liveLoginUrl: {}, liveLoginParam: {}", liveLoginUrl, liveLoginParam);
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("devices_uuid", liveLoginParam);
        paramMap.put("type", "ios");
        String result = HttpUtil.post(liveLoginUrl, paramMap);
        String token = "";
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            JSONObject jsonObject = JSONUtil.parseObj(result);
            String code = jsonObject.getStr("code");
            if ("200".equals(code)) {
                JSONObject dataJson = jsonObject.getJSONObject("data");
                if (StringUtils.isNotNull(dataJson)) {
                    token = dataJson.getStr("token");
                }
            }
            log.info("调用第三方登录接口获取的token值: " + token);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return token;
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取直播列表")
    @GetMapping("/liveList")
    public String liveList(@RequestParam(value = "limit") String limit, @RequestParam(value = "page") String page) {
        log.info("开始调用-获取直播列表接口...");
        String liveListUrl = configService.selectConfigByKey("live_list");
        log.info("获取直播列表: url: {}", liveListUrl);
        String token = liveLogin();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("page", page);
        paramMap.put("limit", limit);
        paramMap.put("token", token);
        String result = HttpUtil.post(liveListUrl, paramMap);
        log.info("获取直播列表: 请求第三方接口后的返回值: {}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("获取直播列表: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("获取直播列表: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-获取直播列表接口!!!");
        return result;
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取最新视频列表")
    @GetMapping("/videoNews")
    public String videoNews(@RequestParam(value = "limit") String limit, @RequestParam(value = "page") String page) {
        log.info("开始调用-获取最新视频列表接口...");
        String liveListUrl = configService.selectConfigByKey("video_news");
        log.info("获取最新视频列表: url: {}", liveListUrl);
        String token = liveLogin();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("page", page);
        paramMap.put("limit", limit);
        paramMap.put("token", token);
        String result = HttpUtil.post(liveListUrl, paramMap);
        log.info("获取最新视频列表: 请求第三方接口后的返回值: {}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("获取最新视频列表: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("获取最新视频列表: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-获取最新视频列表接口!!!");
        return result;
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取直播分类")
    @GetMapping("/videoCate")
    public String videoCate(@RequestParam(value = "cateId") String cateId) {
        log.info("开始调用-获取直播分类接口...");
        String liveListUrl = configService.selectConfigByKey("video_cate");
        log.info("获取直播分类: url: {}", liveListUrl);
        String token = liveLogin();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("category_id", cateId);
        paramMap.put("token", token);
        String result = HttpUtil.post(liveListUrl, paramMap);
        log.info("获取直播分类: 请求第三方接口后的返回值: {}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("获取直播分类: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("获取直播分类: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-获取直播分类接口!!!");
        return result;
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取视频排名")
    @GetMapping("/videoRanking")
    public String videoRanking(@RequestParam(value = "limit") String limit, @RequestParam(value = "page") String page) {
        log.info("开始调用-获取视频排名接口...");
        String liveListUrl = configService.selectConfigByKey("video_ranking");
        log.info("获取视频排名: url: {}", liveListUrl);
        String token = liveLogin();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("page", page);
        paramMap.put("limit", limit);
        paramMap.put("token", token);
        String result = HttpUtil.post(liveListUrl, paramMap);
        log.info("获取视频排名: 请求第三方接口后的返回值: {}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("获取视频排名: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("获取视频排名: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-获取视频排名接口!!!");
        return result;
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取直播详情")
    @PostMapping("/liveInfo")
    public String liveInfo(@RequestParam(value = "name") String name) {
        log.info("开始调用-获取直播详情接口...");
        String liveListUrl = configService.selectConfigByKey("live_info");
        log.info("获取直播详情: liveListUrl: {}", liveListUrl);
        String token = liveLogin();
        HashMap<String, Object> paramMap = new HashMap<>();
        paramMap.put("name", name);
        paramMap.put("token", token);
        String result = HttpUtil.post(liveListUrl, paramMap);
        log.info("获取直播详情: 请求第三方接口后的返回值: {}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("获取直播详情: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("获取直播详情: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-获取直播详情接口!!!");
        return result;
    }

    @ApiOperation("发送请求")
    @PostMapping(value = "/send")
    public AjaxResult send(@Validated @RequestBody InterfaceInfoParam param) {
        log.info("开始调用-发送请求接口...");
        String result = "";
        log.info("接口详情: {}", JSON.toJSONString(param));
        String url = param.getUrl();
        String data = param.getData();
        String method = param.getMethod();
        Map paramMap = (Map) JSON.parse(data);
        if ("GET".equals(method.toUpperCase())) {
            result = HttpUtil.post(url, paramMap);
        } else if("POST".equals(method.toUpperCase())){
            result = HttpUtil.post(url, paramMap);
        }
        log.info("请求结果：{}", result);
        try {
            result = AesUtil.decrypt(new String(result.getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("解密数据: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("解密数据: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-发送请求接口!!!");
        return AjaxResult.success(result);
    }

    @ApiOperation("解密数据")
    @PostMapping(value = "/decrypt")
    public AjaxResult decrypt(@Validated @RequestBody DecryptParam param) {
        log.info("开始调用-解密数据接口...");
        String result = "";
        try {
            log.info("解密数据: 数据源: {}", param);
            result = AesUtil.decrypt(new String(param.getSource().getBytes(), "UTF-8"), "AbpDspjkVNnnXVwg", "tSKANBW7rhGW5hN3");
            result = UnicodeUtil.toString(result);
            log.info("解密数据: 返回值经过解密后的结果: {}", result);
        } catch (UnsupportedEncodingException e) {
            log.error("解密数据: 解密异常");
            e.printStackTrace();
        }
        log.info("结束调用-解密数据接口!!!");
        return AjaxResult.success(result);
    }

    @ApiOperation("获取数据字典列表")
    @GetMapping(value = "/dictData/{dictType}")
    public AjaxResult dictData(@PathVariable String dictType) {
        log.info("开始调用-获取数据字典列表接口...");
        List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
        if (StringUtils.isNull(data)) {
            data = new ArrayList<SysDictData>();
        }
        log.info("结束调用-获取数据字典列表接口!!!");
        return AjaxResult.success(data);
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取视频分类前5名列表")
    @GetMapping("/videoGroupList")
    public AjaxResult videoGroupList() {
        log.info("开始调用-获取视频分类前5名列表接口...");
        List<SysDictData> videoTagDictList = dictTypeService.selectDictDataByType("video_tag");
        List<SysDictData> videoTypeDictList = dictTypeService.selectDictDataByType("video_type");
        List<BusVideoInfo> videoInfoList = videoInfoService.selectVideoListGroupByTypeLimit5();
        videoInfoService.formatVideoList(videoInfoList, videoTagDictList, videoTypeDictList);
        log.info("结束调用-获取视频分类前5名列表接口!!!");
        return AjaxResult.success(videoInfoList);
    }

    /**
     * 获取视频列表
     */
    @ApiOperation("获取视频列表")
    @GetMapping("/videoList")
    public TableDataInfo videoList(BusVideoInfo video) {
        log.info("开始调用-获取视频列表接口...");
        startPage();
        List<BusVideoInfo> list = videoInfoService.selectVideoList(video);
        log.info("结束调用-获取视频列表接口!!!");
        return getDataTable(list);
    }

    /**
     * 根据视频编号获取详细信息
     */
    @ApiOperation("获取视频详情")
    @GetMapping(value = "/video/{videoId}")
    public AjaxResult getInfo(@PathVariable Long videoId) {
        return AjaxResult.success(videoInfoService.selectVideoById(videoId));
    }

    /**
     * 获取轮播图列表
     */
    @ApiOperation("获取轮播图列表")
    @GetMapping("/carouselList")
    public TableDataInfo carouselList() {
        log.info("开始调用-获取轮播图列表接口...");
        List<BusCarouselInfo> list = carouselInfoService.selectCarouselList();
        log.info("结束调用-获取轮播图列表接口!!!");
        return getDataTable(list);
    }

    @ApiOperation("注册会员信息")
    @PostMapping(value = "/register")
    public AjaxResult register(@Validated @RequestBody RegisterParam param, HttpServletRequest request) {
        log.info("开始调用-注册会员信息接口...");
        String rebatePercent = configService.selectConfigByKey("rebate_percent");
        AjaxResult ajax = AjaxResult.success();
        String memberId = cn.hutool.core.util.RandomUtil.randomString(8);   // 会员ID
        String promCode = cn.hutool.core.util.RandomUtil.randomString(6);   // 会员自己的推广码
        String memberIp = IpUtils.getIpAddr(ServletUtils.getRequest());
        String memberName = RandomUtil.generate8RateUuid();
        BusMemberInfo memberInfo = new BusMemberInfo();
        memberInfo.setMemberId(memberId);
        memberInfo.setMemberName(memberName);
        memberInfo.setVipDueTime(new Date());
        memberInfo.setPlatform(param.getPlatform());
        memberInfo.setPromCode(promCode);
        memberInfo.setMemberIp(memberIp);
        memberInfo.setRebatePercent(StringUtils.isEmpty(rebatePercent) ? 70 : Integer.parseInt(rebatePercent));
        // 根据IP查询刚刚下载的信息，查到推广码，根据推广码查询到推广用户
        BusDownloadInfo downloadInfo = downloadInfoService.selectDownloadByIp(memberIp);
        if (StringUtils.isNotNull(downloadInfo) && StringUtils.isNotEmpty(downloadInfo.getPromCode())) {
            BusMemberInfo pMemberInfo = memberInfoService.selectMemberByPromCode(downloadInfo.getPromCode());   // 推广员
            if (StringUtils.isNotNull(pMemberInfo) && StringUtils.isNotEmpty(pMemberInfo.getMemberId())) {
                memberInfo.setpMemberId(pMemberInfo.getMemberId());
            }
        }
        log.info("会员注册: {}", JSONUtil.toJsonStr(memberInfo));
        memberInfoService.insertMember(memberInfo);
        ajax.put("memberInfo", memberInfo);
        log.info("结束调用-注册会员信息接口!!!");
        return ajax;
    }

    @ApiOperation("获取会员详情")
    @GetMapping(value = "/member/{memberId}")
    public AjaxResult getInfo(@PathVariable String memberId) {
        log.info("开始调用-获取会员详情接口...");
        BusMemberInfo memberInfo = memberInfoService.selectMemberById(memberId);
        if (memberInfo == null || StringUtils.isEmpty(memberInfo.getMemberId())) {
            return AjaxResult.error("用户信息不存在");
        }
        BusMemberInfo pMemberInfo = memberInfoService.selectMemberById(memberInfo.getpMemberId());
        memberInfo.setpMemberInfo(pMemberInfo);
        int memberNum = 0;
        int downloadNum = 0;
        int rebatePercent = memberInfo.getRebatePercent();
        List<PromDetailDTO> promotionList = new ArrayList<>();
        List<BusMemberInfo> memberInfoList = memberInfoService.selectMemberListByPId(memberId); // 子会员信息
        if (StringUtils.isNotEmpty(memberInfoList)) {
            memberNum = memberInfoList.size();
            promotionList = memberInfoService.selectPromStatisticsByPMemberId(memberId, rebatePercent);  // 推广信息
        }
        List<BusDownloadInfo> downloadList = downloadInfoService.selectDownloadListByPromCode(memberInfo.getPromCode());
        if (StringUtils.isNotEmpty(downloadList)) {
            downloadNum = downloadList.size();
        }
        memberInfo.setPromotionStatistics(new PromListDetailDTO(memberNum, downloadNum, promotionList));
        log.info("结束调用-获取会员详情接口!!!");
        return AjaxResult.success(memberInfo);
    }

    @ApiOperation("获取用户收藏列表")
    @GetMapping("/store/{memberId}")
    public TableDataInfo list(@PathVariable("memberId")String memberId) {
        log.info("开始调用-获取用户收藏列表接口...");
        List<BusMemberStore> storeList = memberStoreService.selectMemberStoreList(memberId);
        List<BusVideoInfo> videoInfoList = new ArrayList<>();
        List<Long> videoIdList = new ArrayList<>();
        for (BusMemberStore store : storeList) {
            videoIdList.add(store.getVideoId());
        }
        if (videoIdList == null || videoIdList.size() == 0) {
            return getDataTable(videoInfoList);
        }
        startPage();
        List<SysDictData> videoTagDictList = dictTypeService.selectDictDataByType("video_tag");
        List<SysDictData> videoTypeDictList = dictTypeService.selectDictDataByType("video_type");
        videoInfoList = videoInfoService.selectVideoByIdList(videoIdList);
        videoInfoService.formatVideoList(videoInfoList, videoTagDictList, videoTypeDictList);
        log.info("结束调用-获取用户收藏列表接口!!!");
        return getDataTable(videoInfoList);
    }

    @ApiOperation("保存收藏信息")
    @PostMapping(value="/store")
    public AjaxResult store(@Validated @RequestBody MemberStoreParam param) {
        log.info("开始调用-保存收藏信息接口...");
        BusMemberStore memberStore = new BusMemberStore();
        List<BusMemberStore> memberStoreList = memberStoreService.selectMemberStore(param.getVideoId(), param.getMemberId());
        if (memberStoreList != null && memberStoreList.size() > 0) {
            log.info("结束调用-保存收藏信息接口!!!");
            return AjaxResult.success();
        }
        try {
            memberStore.setVideoId(param.getVideoId());
            memberStore.setMemberId(param.getMemberId());
            memberStoreService.insertMemberStore(memberStore);
            log.info("结束调用-保存收藏信息接口!!!");
            return AjaxResult.success();
        } catch (Exception e) {
            log.info("结束调用-保存收藏信息接口!!!");
            return AjaxResult.error(e.getMessage());
        }
    }

    @ApiOperation("取消收藏信息")
    @DeleteMapping(value="/store/{videoId}/{memberId}")
    public AjaxResult store(@PathVariable("videoId") Long videoId, @PathVariable("memberId")String memberId) {
        return AjaxResult.success(memberStoreService.deleteMemberStoreById(videoId, memberId));
    }

    /**
     * 新增激活码
     */
    @ApiOperation("激活激活码信息")
    @PutMapping(value = "/active")
    public AjaxResult active(@Validated @RequestBody ActiveCodeEditParam param) {
        log.info("开始调用-激活激活码信息接口...");
        if (StringUtils.isNull(param) || StringUtils.isNull(param.getActiveCode()) || StringUtils.isNull(param.getMemberId())) {
            return AjaxResult.error("参数不能为空");
        }
        BusActiveCode activeCode = activeCodeService.selectActiveCodeByCode(param.getActiveCode());
        BusMemberInfo memberInfo = memberInfoService.selectMemberById(param.getMemberId());
        if (StringUtils.isNull(activeCode)) {
            return AjaxResult.error("激活码不存在");
        }
        if("1".equals(activeCode.getActiveUsed())) {    // 激活码是否使用，0：未使用，1：已使用
            return AjaxResult.error("激活码已经被使用");
        }
        if (StringUtils.isNull(memberInfo)) {
            return AjaxResult.error("用户不存在");
        }
        Date date = new Date();
        int days = Integer.parseInt(activeCode.getActiveDays());
        String activeEndTime = DateUtils.getDateAfter(date, days, DateUtils.YYYY_MM_DD_HH_MM_SS);
        String memberEndTime = "";
        Date vipDueDateTime = memberInfo.getVipDueTime();
        int result = vipDueDateTime.compareTo(date);
        if (result < 0) {
            memberEndTime = activeEndTime;
        } else {
            memberEndTime = DateUtils.getDateAfter(memberInfo.getVipDueTime(), days, DateUtils.YYYY_MM_DD_HH_MM_SS);
        }
        activeCode.setActiveUsed("1");
        activeCode.setMemberId(param.getMemberId());
        activeCode.setActiveStartTime(date);
        activeCode.setActiveEndTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, activeEndTime));
        memberInfo.setVipDueTime(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, memberEndTime));
        activeCodeService.active(activeCode, memberInfo);
        log.info("结束调用-激活激活码信息接口!!!");
        return AjaxResult.success();
    }

    /**
     * 新增激活码
     */
    @ApiOperation("绑定推广码信息")
    @PutMapping(value = "/bind")
    public AjaxResult bind(@Validated @RequestBody BindPromCodeParam param) {
        log.info("开始调用-绑定推广码信息接口...");
        if (StringUtils.isNull(param) || StringUtils.isNull(param.getPromCode()) || StringUtils.isNull(param.getMemberId())) {
            return AjaxResult.error("参数不能为空");
        }
        BusMemberInfo memberInfo = memberInfoService.selectMemberById(param.getMemberId());         // 会员自身
        BusMemberInfo pMemberInfo = memberInfoService.selectMemberByPromCode(param.getPromCode());   // 推广员
        if (StringUtils.isNull(pMemberInfo)) {
            return AjaxResult.error("推广员信息不存在");
        }
        if (StringUtils.isNull(memberInfo)) {
            return AjaxResult.error("用户不存在");
        }
        if (StringUtils.isNotNull(memberInfo.getpMemberId())) {
            return AjaxResult.error("用户已经绑定过推广码");
        }
        // 推广员的ID和会员的IP来判断该IP下的会员是不是盗刷推广员的推广码
        List<BusMemberInfo> memberInfoList = memberInfoService.selectMemberListByPIdAndIp(pMemberInfo.getMemberId(), memberInfo.getMemberIp());
        if (memberInfoList != null && memberInfoList.size() > 0) {
            return AjaxResult.error("该IP已经绑定过推广码");
        }
        memberInfo.setpMemberId(pMemberInfo.getMemberId());
        memberInfoService.updateMember(memberInfo);
        log.info("结束调用-绑定推广码信息接口!!!");
        return AjaxResult.success();
    }

    @ApiOperation("生成二维码")
    @GetMapping("/qrCode/{promCode}")
    public AjaxResult qrCode(@PathVariable("promCode")String promCode) {
        log.info("开始调用-生成二维码接口...");
        String promoQrUrl = configService.selectConfigByKey("promo_qr_url");
        String promoQrLogo = configService.selectConfigByKey("promo_qr_logo");
        String filePath = RuoYiConfig.getUploadPath();  // 上传文件路径
        String fileName = DateUtils.datePath() + "/" + "qr" + "_" + promCode + "_" + DateUtils.dateTimeNow() + ".jpg";
        String fileUrl = "";
        try {
            log.info("二维码路径: {}", filePath);
            log.info("二维码名称: {}", fileName);
            File qrFile = FileUploadUtils.getAbsoluteFile(filePath, fileName);
            log.info("二维码文件: {} {}", fileName, qrFile.exists() ? "创建成功" : "创建失败");
            // 生成指定url对应的二维码到文件，宽和高都是300像素
            // QrCodeUtil.generate(promoQrUrl, 300, 300, FileUtil.file(filePath + File.separator + fileName));
            QrCodeUtil.generate(//
                    promoQrUrl + "?promCode=" + promCode,     //二维码内容
                    QrConfig.create().setImg(promoQrLogo), //附带logo
                    FileUtil.file(filePath + File.separator + fileName)//写出到的文件
            );
            log.info("生成二维码成功: {}", fileName);
            fileUrl = FileUploadUtils.getPathFileName(filePath, fileName);
            fileUrl = serverConfig.getUrl() + fileUrl;
            log.info("二维码访问路径: {}", fileUrl);
        } catch (IOException e) {
            e.printStackTrace();
            return AjaxResult.error("二维码生成失败");
        }
        log.info("结束调用-生成二维码接口!!!");
        return AjaxResult.success(fileUrl);
    }

    @ApiOperation("扫码下载接口信息")
    @PostMapping(value="/scanDown")
    public AjaxResult store(@Validated @RequestBody ScanDownloadParam param, HttpServletRequest request) {
        log.info("开始调用-扫码下载接口信息接口...");
        // 扫码下载后，前端需要调用此接口，后台需要保存Ip和推广码
        String memberIp = IpUtils.getIpAddr(ServletUtils.getRequest());
        String promCode = param.getPromCode();
        BusDownloadInfo downloadInfo = downloadInfoService.selectDownloadByIp(memberIp);
        if (downloadInfo == null) {
            downloadInfo = new BusDownloadInfo();
            downloadInfo.setDownIp(memberIp);
            downloadInfo.setPromCode(promCode);
            downloadInfo.setPromBind("0");
            downloadInfoService.insertDownload(downloadInfo);
        } else {
            // 还未绑定推广码，又下载一次，则推广码则更新为最后一次下的的推广码
            if ("0".equals(downloadInfo.getPromBind())) {
                downloadInfo.setPromCode(promCode);
                downloadInfo.setPromBind("0");
                downloadInfo.setUpdateTime(new Date());
                downloadInfoService.updateDownload(downloadInfo);
            }
            // 若已经绑定过推广码，则再下载不做任何操作
        }
        log.info("结束调用-扫码下载接口信息接口!!!");
        return AjaxResult.success();
    }

    /**
     * 新增轮播图
     */
    @ApiOperation("上传文件")
    @PostMapping("/importFile")
    public AjaxResult importFile(MultipartFile file) {
        try {
            String filePath = RuoYiConfig.getUploadPath();  // 上传文件路径
            String fileName = FileUploadUtils.upload(filePath, file);
            String fileUrl = serverConfig.getUrl() + fileName;
            return AjaxResult.success(fileUrl);
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    @ApiOperation("android密文加密-新2022.06.12")
    @GetMapping(value = "/android_encrypt")
    public AjaxResult androidEncrypt(@RequestParam String str) {
        log.info("开始调用-加密接口...");
        if (StringUtils.isNull(str)) {
            return AjaxResult.error("原始内容不能为空，例如：密文（Yd9Y+QmLwh7LuHC2R+2ItQ==），解析出来的结果应该是（hello world）");
        }
        System.out.println("resource: " + str);
        DecryptString.getInstance().setsKey("3178172413845564");
        String result = DecryptString.getInstance().encrypt(str);
        System.out.println("result: " + result);
        log.info("结束调用-加密接口!!!");
        return AjaxResult.success(result);
    }

    @ApiOperation("android密文解密-新2022.06.12")
    @GetMapping(value = "/android_decrypt")
    public AjaxResult androidDecrypt(@RequestParam String str) {
        log.info("开始调用-解密接口...");
        if (StringUtils.isNull(str)) {
            return AjaxResult.error("密文不能为空，例如：密文（Yd9Y+QmLwh7LuHC2R+2ItQ==），解析出来的结果应该是（hello world）");
        }
        System.out.println("resource: " + str);
        DecryptString.getInstance().setsKey("3178172413845564");
        String result = DecryptString.getInstance().decrypt(str);
        System.out.println("result: " + result);
        log.info("结束调用-解密接口!!!");
        return AjaxResult.success(result);
    }

}
